import Cocoa

//var str = "Hello, playground"

/**
 extension:
 1. 扩展为现有的类,结构体,枚举类型,或协议添加了新功能. 这也包括了为无权访问权限的源代码扩展类型的能力(即逆向建模)
 2. Swift中的扩展和Objective-C中的Category类似.(与OC中的分类不同的是,Swift的扩展没有名字)
*/

/**
 extension的能力:
 1. 添加计算类型属性和计算实例属性,但是不能创建存储属性, 因为存储属性在初始化时,他的内存是稳定的,一旦在扩展中创建新的存储属性,就要增加内存空间
 2. 定义实例方法和类型方法(也就是oc中的对象方法和类方法)
 3. 提供新初始化器(可以为类添加新的便捷初始化器, 不能为类添加指定初始化器和反初始化器).指定初始化器和反初始化器必须由原来类的实现提供
 4. 定义下标
 5. 定义和使用新内嵌类型
 6. 使现有的类型遵循某协议
 7. 扩展可以向一个类型添加新的方法,但是不能重写已有的方法
 */

//扩展可以向已有的类型添加计算类型属性和计算实例属性
extension Double {   //扩展Double类型
    var km: Double {  //为计算属性添加扩展,计算属性相当于方法
        return self * 1000.0
    }
    var m: Double {
       return self
    }
    var cm: Double {
        return self / 100.0
    }
    var mm: Double {
        return self / 1000.0
    }
}
let number = 1.2.km
print("number is \(number)")


//扩展可以向已有的类型添加新的初始化器,但是只能添加便捷初始化器
struct Size {
    var width = 0.0
    var height = 0.0
}
struct Point {
    var x = 0.0
    var y = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
}
extension Rect {  //扩展Rect类型
    init(center: Point, size: Size) {  //为Rect类添加便捷初始化器
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size) //便捷初始化器必须要先委托自己类的其他初始化器
    }
}
let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))
print("originX is \(centerRect.origin.x), originY is \(centerRect.origin.y)")


//扩展可以为现有的类型添加新的实例方法和类型方法
extension Int {
    func repeatTask(_ task: () -> ()){   //扩展为现有的类型添加实例方法
        for _ in 0 ..< self {
            task()
        }
    }
}
3.repeatTask {
    print("hello")   //输出结果:打印了三次 "hello"
}


//扩展的修改任可以修改(或异变)实例本身. 结构体和枚举类型方法在修改 self 或本身的 属性时必须标记实例方法为 mutating ，和原本实现的异变方法一样。
extension Int {
    mutating func square () {
        self = self * self  //获取一个数的平方
    }
}
var someInt = 3
someInt.square()


//扩展能为已有的类型添加新的下标
extension Int {
    subscript (digitIndex: Int) -> Int {
        var base = 1
        for _ in 0..<digitIndex {
            base *= 10
        }
       return (self / base) % 10
    }
}
746381295[0]   //这个数的第0位是: 5
746381295[1]
746381295[3]
746381295[8]

//扩展可以为已有的类,结构体和枚举类型添加新的内嵌类型
extension Int {
    enum Kind {
        case negative
        case zero
        case positive
    }
    var kind: Kind {
        switch self {
        case 0:
            return .zero
        case let x where x > 0:
            return .positive  //正数
        default:
            return .negative  //负数
        }
    }
}
print(8.kind)
